package com.spider.pipeline;

import com.spider.entites.Filed;
import com.spider.utils.StringUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import us.codecraft.webmagic.ResultItems;
import us.codecraft.webmagic.Task;
import us.codecraft.webmagic.pipeline.Pipeline;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 列表页数据执行器
 *
 * @author panglin
 * @date 2020/11/20 21:40
 */
@Component
@Scope("prototype")
public class ListPagePipeline implements Pipeline {

    private static final Logger LOGGER = LoggerFactory.getLogger(ListPagePipeline.class);

    /**
     * 字段总数
     */
    private List<Filed> filed;

    /**
     * 表名，主表和从表
     */
    private String tbName;

    /**
     * 查询工具
     */
    private QueryRunner queryRunner;

    public Pipeline initPipeline(List<Filed> fileds,String tbName,QueryRunner queryRunner){
        this.filed = fileds;
        this.tbName = tbName;
        this.queryRunner = queryRunner;
        return this;
    }

    /**
     * 将爬取的数据写入数据库中
     *
     * @param resultItems
     * @param task
     */
    @Override
    public void process(ResultItems resultItems, Task task) {
        List<String> filed = new ArrayList<>();
        List<String[]> list = new ArrayList<>();
        this.filed.forEach(f -> {
            String str = resultItems.get(f.getFiled()).toString();
            String data = str.substring(1, str.length() - 1).trim();
            if (StringUtils.isNotEmpty(data)) {
                filed.add(f.getFiled());
                list.add(data.split(","));
            }
        });
        if (filed.size() != 0) {
            this.finishCurrPage(this.generateSql(filed), this.generateParams(filed, list));
        } else {
            LOGGER.info("当前列表页没有数据{}", this.tbName);
        }
    }

    /**
     * 生成参数
     *
     * @param filed
     * @param list
     * @return
     */
    private Object[][] generateParams(List<String> filed, List<String[]> list) {
        int size = filed.size();
        int len = list.get(0).length;
        Object[][] params = new Object[len][];
        for (int i = 0; i < len; i++) {
            params[i] = new Object[size];
            for (int j = 0; j < size; j++) {
                try {
                    params[i][j] = list.get(j)[i].trim();
                } catch (Exception e) {
                    LOGGER.info("当前列表页部分数据残缺,残缺字段:{}", filed.get(j));
                }
            }
        }
        return params;
    }

    /**
     * 插入当前列表页的数据
     *
     * @param sql
     * @param params
     */
    private void finishCurrPage(String sql, Object[][] params) {
        try {
            this.queryRunner.batch(sql, params);
        } catch (SQLException throwable) {
            throwable.printStackTrace();
        }
        LOGGER.info("当前列表页执行完毕,table:{}", this.tbName);
    }

    /**
     * 生成sql
     *
     * @param filed
     * @return
     */
    private String generateSql(List<String> filed) {
        StringBuilder prefix = new StringBuilder("insert into " + this.tbName + "(");
        StringBuilder suffix = new StringBuilder("values(");
        for (String f : filed) {
            prefix.append(f).append(",");
            suffix.append("?,");
        }
        prefix = new StringBuilder(prefix.substring(0, prefix.length() - 1) + ") ");
        suffix = new StringBuilder(suffix.substring(0, suffix.length() - 1) + ")");
        LOGGER.info("列表页sql:{}", prefix + suffix.toString());
        return prefix.append(suffix).toString();
    }
}
